package com.molichuxing.gateway.api.aspect;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * 参数全局日志
 * 
 * @author zoumingyu
 * @date 2019年8月8日
 *
 */
@Aspect
@Order(3)
@Component
public class WebLogAspect {
	private final static Logger logger = LoggerFactory.getLogger("[op-gateway参数全局日志]");

	private final static String NEWLINE = "\r\n        =====>";

	@Pointcut("execution(public * com.molichuxing.gateway.api.services.impl..*(..))")
	public void webLog() {
	}

	@Before("webLog()")
	public void doBefore(JoinPoint joinPoint) {
		StringBuffer sb = new StringBuffer();
		try {
			ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
					.getRequestAttributes();
			HttpServletRequest request = attributes.getRequest();
			sb.append("[" + Thread.currentThread().getId() + "]");
			sb.append(NEWLINE + "URL : " + request.getRequestURL());
			if (request.getQueryString() != null) {
				sb.append(NEWLINE + "QueryString : " + request.getQueryString());
			}
			sb.append(NEWLINE + "HTTP_METHOD : " + request.getMethod());
			sb.append(NEWLINE + "IP : " + request.getRemoteAddr());
			sb.append(NEWLINE + "CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "."
					+ joinPoint.getSignature().getName());
			ObjectMapper mapper = new ObjectMapper();
			try {
				for (Object obj : joinPoint.getArgs()) {
					if (obj != null && obj instanceof ServletRequest) {
						continue;
					} else if (obj != null && obj instanceof ServletResponse) {
						continue;
					} else if (obj != null && obj instanceof BindingResult) {
						continue;
					} else if (obj != null && obj instanceof MultipartFile) {
						continue;
					} else if (obj != null && obj instanceof MultipartFile[]) {
						continue;
					}
					sb.append(NEWLINE + "参数 : " + (obj == null ? "null" : mapper.writeValueAsString(obj)));
				}
			} catch (Exception e) {
				sb.append(NEWLINE + "参数 : 参数序列化异常。");
				e.printStackTrace();
			}
		} finally {
			logger.info(sb.toString() + "\r\n");
		}
	}

	@AfterReturning(returning = "returnValue", pointcut = "webLog()")
	public void doAfterReturning(Object returnValue) {
		StringBuffer sb = new StringBuffer();
		sb.append("[" + Thread.currentThread().getId() + "]");
		try {
			ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
					.getRequestAttributes();
			HttpServletRequest request = attributes.getRequest();
			ObjectMapper mapper = new ObjectMapper();
			sb.append(NEWLINE + "URL : " + request.getRequestURL());
			sb.append(NEWLINE + "返回内容：" + mapper.writeValueAsString(returnValue));
		} catch (Exception ex) {
			sb.append(NEWLINE + "返回内容：对返回值序列化时发生异常。");
		}

		logger.info(sb.toString() + "\r\n");
	}
}
